/*

    array.cpp - implementation of the array class
    Author Julio Agustin Barrera Mendoza
    Copyright (C) 2009 CINVESTAV-IPN.

    This program is free software; you can redistribute it and/or modify it 
    under the terms of the GNU General Public License as published by 
    the Free Software Foundation; either version 2 of the License, 
    or (at your option) any later version.

    This program is distributed in the hope that it will be useful, 
    but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
    FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along with this program; 
    if not, write to the Free Software Foundation, Inc., 59 Temple Place, 
    Suite 330, Boston, MA 02111-1307 USA

 */

#include "array.h"

// ------------------------------------------------------------------
// FUNCTION Array::Array
// ------------------------------------------------------------------

Array::Array()
{
}

// ------------------------------------------------------------------
// FUNCTION Array::Array
// ------------------------------------------------------------------

Array::Array(unsigned int inSize, long double inValue)
{
  array.assign(inSize, inValue);
}

// ------------------------------------------------------------------
// FUNCTION Array::~Array
// ------------------------------------------------------------------

Array::~Array()
{
}

// ------------------------------------------------------------------
// FUNCTION Array::Norm
// ------------------------------------------------------------------

long double Array::Norm(void)
{
  unsigned int i, elements = size();
  long double result = 0.0;

  for (i = 0; i < elements; i++)
    result += array[i] * array[i];
    
  result = sqrtl(result);
  
  return result;
}

// ------------------------------------------------------------------
// FUNCTION Array::operator+=
// ------------------------------------------------------------------

Array &Array::operator+=(const Array &rh)
{
  unsigned int i, elements = rh.size();
  
  for (i = 0; i < elements; i++)
    array[i] += rh[i];

  return (*this);
}

// ------------------------------------------------------------------
// FUNCTION Array::operator-=
// ------------------------------------------------------------------

Array &Array::operator-=(const Array &rh)
{
  unsigned int i, elements = rh.size();
  
  for (i = 0; i < elements; i++)
    array[i] -= rh[i];

  return (*this);
}

// ------------------------------------------------------------------
// FUNCTION operator+
// ------------------------------------------------------------------

const Array operator+(const Array &lh, const Array &rh)
{
  unsigned int i, elements = lh.size();
  Array result(elements);
  
  for (i = 0; i < elements; i++)
    result[i] = lh[i] + rh[i];
    
  return result;
}

// ------------------------------------------------------------------
// FUNCTION operator-
// ------------------------------------------------------------------

const Array operator-(const Array &lh, const Array &rh)
{
  unsigned int i, elements = lh.size();
  Array result(elements);
  
  for (i = 0; i < elements; i++)
    result[i] = lh[i] - rh[i];
    
  return result;
}

// ------------------------------------------------------------------
// FUNCTION operator*
// ------------------------------------------------------------------

const Array operator*(const long double &lh, const Array &rh)
{
  unsigned int i, elements = rh.size();
  Array result(elements);
  
  for (i = 0; i < elements; i++)
    result[i] = lh * rh[i];
    
  return result;
}

// ------------------------------------------------------------------
// FUNCTION operator*
// ------------------------------------------------------------------

const Array operator*(const Array &lh, const long double &rh)
{
  unsigned int i, elements = lh.size();
  Array result(elements);
  
  for (i = 0; i < elements; i++)
    result[i] = lh[i] * rh;
    
  return result;
}

// ------------------------------------------------------------------
// FUNCTION operator<<
// ------------------------------------------------------------------

ostream &operator<<(ostream &output, const Array &rh)
{
  unsigned int i, variables = rh.array.size();
  unsigned int limit = variables - 1;
    
  for (i = 0; i < variables; i++)
    {
      output << rh.array[i];
      if (i < limit)
        output << " ";
    }

  return output;
}

// ------------------------------------------------------------------
// FUNCTION CartesianProduct
// ------------------------------------------------------------------

const Array CartesianProduct(const Array &lh, const Array &rh)
{
  unsigned int i, elements = lh.size();
  Array result(elements);
  
  for (i = 0; i < elements; i++)
    result[i] = lh[i] * rh[i];
    
  return result;
}    
    
// ------------------------------------------------------------------
// FUNCTION DotProduct
// ------------------------------------------------------------------

long double DotProduct(const Array &lh, const Array &rh)
{
  unsigned int i, elements = lh.size();
  long double result = 0.0;
  
  for (i = 0; i < elements; i++)
    result += lh[i] * rh[i];
    
  return result;
}

// ------------------------------------------------------------------
// FUNCTION Distance
// ------------------------------------------------------------------

long double Distance(const Array &lh, const Array &rh)
{
  unsigned int i, elements = lh.size();
  long double result = 0.0;
  
  for (i = 0; i < elements; i++)
    result += (rh[i] - lh[i]) * (rh[i] - lh[i]);
    
  result = sqrtl(result);
    
  return result;
}
